// 在文件顶部添加类型声明
declare const uni: any;
declare function getCurrentPages(): any[];

import type { ErrorInfo, ReportResponse } from '../types';
import type { ConfigManager } from './ConfigManager';
import type { PlatformAdapter } from './PlatformAdapter';
import { PlatformType } from '../types';

// 添加缓存错误信息的接口
interface CachedErrorInfo extends ErrorInfo {
  retryCount: number;
  cachedAt: number;
}

export class ErrorReporter {
  private reportQueue: ErrorInfo[] = [];
  private isReporting = false;
  private flushTimer?: number;
  private isOnline = true;
  private readonly CACHE_KEY = 'uni_error_cache';
  private readonly MAX_CACHE_SIZE = 100; // 最大缓存100条错误
  private readonly MAX_RETRY_COUNT = 3;
  private readonly CACHE_EXPIRE_TIME = 7 * 24 * 60 * 60 * 1000; // 7天过期

  constructor(
    private configManager: ConfigManager,
    private platformAdapter: PlatformAdapter
  ) {
    this.initNetworkListener();
  }

  async init(): Promise<void> {
    this.startFlushTimer();
    // 初始化时尝试上报缓存的错误
    await this.retryCachedErrors();
  }

  async report(errorInfo: ErrorInfo): Promise<void> {
    const config = this.configManager.getConfig();
    
    // 添加到队列
    this.reportQueue.push(errorInfo);
    
    // 如果队列达到批量大小，立即上报
    if (this.reportQueue.length >= config.batchSize) {
      await this.flush();
    } else {
      // 对于测试环境，立即上报单个错误
      if (process.env.NODE_ENV === 'test') {
        await this.flush();
      }
    }
  }

  private async flush(): Promise<void> {
    if (this.isReporting || this.reportQueue.length === 0) {
      return;
    }
    
    this.isReporting = true;
    const config = this.configManager.getConfig();
    const errors = this.reportQueue.splice(0, config.batchSize);
    
    try {
      for (const error of errors) {
        await this.sendError(error);
      }
    } catch (err) {
      // 上报失败，重新加入队列
      this.reportQueue.unshift(...errors);
      console.error('[ErrorReporter] 上报失败:', err);
    } finally {
      this.isReporting = false;
    }
  }

  private async sendError(errorInfo: ErrorInfo): Promise<ReportResponse> {
    const config = this.configManager.getConfig();
    
    const url = `${config.baseURL}/api/logs/errors/`;
    
    const payload = {
      project: parseInt(config.projectId),
      level: errorInfo.level.toUpperCase(),
      message: errorInfo.message,
      stack_trace: errorInfo.stack_trace,
      user_agent: errorInfo.user_agent || this.getUserAgent(),
      ip_address: errorInfo.ip_address,
      url: errorInfo.url || this.getCurrentUrl(),
      // 添加缺失的字段
      breadcrumbs: errorInfo.user_behavior || null,
      context: errorInfo.custom_data || null,
      performance: errorInfo.performance_data || null,
      environment: errorInfo.device_info || null,
      ...config.customFields
    };
    
    return this.makeRequest(url, payload);
  }

  private async makeRequest(url: string, data: any, retryCount = 0): Promise<ReportResponse> {
    const config = this.configManager.getConfig();
    const platformType = this.platformAdapter.getPlatformType();
    const maxRetries = this.MAX_RETRY_COUNT;
    console.log(`[ErrorReporter] 平台: ${platformType}, URL: ${url}`);

    // 检查网络状态
  try {
    const networkInfo = await this.getNetworkInfo();
    console.log(`[ErrorReporter] 网络状态:`, networkInfo);
  } catch (e) {
    console.warn('[ErrorReporter] 无法获取网络状态:', e);
  }
    return new Promise((resolve, reject) => {
      const handleError = async (error: Error) => {
        console.log(`[ErrorReporter] 请求失败: ${error.message}`);
        
        // 如果是网络错误且重试次数未达上限，缓存错误信息
        if (this.isNetworkError(error) && retryCount < maxRetries) {
          await this.cacheError(data, retryCount);
          reject(new Error(`网络请求失败，已缓存待重试: ${error.message}`));
        } else if (retryCount < maxRetries) {
          // 非网络错误，进行重试
          setTimeout(() => {
            this.makeRequest(url, data, retryCount + 1)
              .then(resolve)
              .catch(reject);
          }, 1000 * Math.pow(2, retryCount));
        } else {
          // 达到最大重试次数，缓存错误
          await this.cacheError(data, retryCount);
          reject(error);
        }
      };

      if (platformType === PlatformType.H5) {
        // H5环境：使用fetch API
        if (typeof fetch !== 'undefined') {
          fetch(url, {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
              'Authorization': `Bearer ${config.apiKey}`
            },
            body: JSON.stringify(data)
          })
          .then(response => {
            if (response.ok) {
              return response.json();
            }
            throw new Error(`HTTP ${response.status}`);
          })
          .then(data => {
            resolve({ success: true, errorId: data?.id });
          })
          .catch(handleError);
        } else {
          reject(new Error('fetch API不可用'));
        }
      } else {
        // 非H5环境：使用uni.request
        // 在makeRequest方法中的uni.request配置
        uni.request({
          url,
          method: 'POST',
          header: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${config.apiKey}`,
            'User-Agent': this.getUserAgent() // 添加User-Agent
          },
          data,
          timeout: 15000, // App环境增加超时时间
          dataType: 'json',
          responseType: 'text',
          sslVerify: false, // App环境下可以禁用SSL验证（仅开发阶段）
          success: (res: any) => {
            console.log(`[ErrorReporter] App请求成功:`, res);
            if (res.statusCode >= 200 && res.statusCode < 300) {
              resolve({ success: true, errorId: (res.data as any)?.id });
            } else {
              handleError(new Error(`HTTP ${res.statusCode}: ${JSON.stringify(res.data)}`));
            }
          },
          fail: (err: any) => {
            console.log(`[ErrorReporter] App请求失败详情:`, {
              errMsg: err.errMsg,
              statusCode: err.statusCode,
              data: err.data,
              header: err.header
            });
            handleError(new Error(`App网络请求失败: ${err.errMsg}`));
          }
        });
      }
    });
  }

  private getNetworkInfo(): Promise<any> {
    return new Promise((resolve) => {
      uni.getNetworkType({
        success: resolve,
        fail: () => resolve({ networkType: 'unknown' })
      });
    });
  }

  private isNetworkError(error: Error): boolean {
    const networkErrorKeywords = [
      'network',
      'timeout',
      'abort',
      'connection',
      'unreachable',
      'fail',
      'statusCode:-1'
    ];
    
    return networkErrorKeywords.some(keyword => 
      error.message.toLowerCase().includes(keyword)
    );
  }

  private async cacheError(errorData: any, retryCount: number): Promise<void> {
    try {
      const cachedError: CachedErrorInfo = {
        ...errorData,
        retryCount,
        cachedAt: Date.now()
      };

      // 获取现有缓存
      const existingCache = this.getCachedErrors();
      
      // 添加新错误到缓存
      existingCache.push(cachedError);
      
      // 限制缓存大小
      if (existingCache.length > this.MAX_CACHE_SIZE) {
        existingCache.splice(0, existingCache.length - this.MAX_CACHE_SIZE);
      }
      
      // 保存到本地存储
      uni.setStorageSync(this.CACHE_KEY, existingCache);
      
      console.log(`[ErrorReporter] 错误已缓存，当前缓存数量: ${existingCache.length}`);
    } catch (err) {
      console.error('[ErrorReporter] 缓存错误失败:', err);
    }
  }

  private getCachedErrors(): CachedErrorInfo[] {
    try {
      const cached = uni.getStorageSync(this.CACHE_KEY);
      if (Array.isArray(cached)) {
        // 过滤过期的缓存
        const now = Date.now();
        return cached.filter((item: CachedErrorInfo) => 
          now - item.cachedAt < this.CACHE_EXPIRE_TIME
        );
      }
    } catch (err) {
      console.error('[ErrorReporter] 读取缓存失败:', err);
    }
    return [];
  }

  private async retryCachedErrors(): Promise<void> {
    if (!this.isOnline) {
      return;
    }

    const cachedErrors = this.getCachedErrors();
    if (cachedErrors.length === 0) {
      return;
    }

    console.log(`[ErrorReporter] 开始重试 ${cachedErrors.length} 个缓存的错误`);
    
    const successfullyReported: number[] = [];
    
    for (let i = 0; i < cachedErrors.length; i++) {
      const cachedError = cachedErrors[i];
      
      try {
        // 移除缓存相关字段
        const { retryCount, cachedAt, ...errorData } = cachedError;
        
        await this.sendError(errorData as ErrorInfo);
        successfullyReported.push(i);
        console.log(`[ErrorReporter] 缓存错误上报成功`);
      } catch (err) {
        console.log(`[ErrorReporter] 缓存错误重试失败: ${err}`);
        // 如果重试失败，增加重试次数
        if (cachedError.retryCount < this.MAX_RETRY_COUNT) {
          cachedErrors[i].retryCount++;
        }
      }
    }
    
    // 移除成功上报的错误
    const remainingErrors = cachedErrors.filter((_, index) => 
      !successfullyReported.includes(index)
    );
    
    // 更新缓存
    uni.setStorageSync(this.CACHE_KEY, remainingErrors);
    
    if (successfullyReported.length > 0) {
      console.log(`[ErrorReporter] 成功上报 ${successfullyReported.length} 个缓存的错误`);
    }
  }

  // 添加清理缓存的方法
  clearCache(): void {
    try {
      uni.removeStorageSync(this.CACHE_KEY);
      console.log('[ErrorReporter] 缓存已清理');
    } catch (err) {
      console.error('[ErrorReporter] 清理缓存失败:', err);
    }
  }

  // 获取缓存统计信息
  getCacheStats(): { count: number; oldestCacheTime: number | null } {
    const cachedErrors = this.getCachedErrors();
    return {
      count: cachedErrors.length,
      oldestCacheTime: cachedErrors.length > 0 
        ? Math.min(...cachedErrors.map(e => e.cachedAt))
        : null
    };
  }

  private initNetworkListener(): void {
    // 监听网络状态变化
    if (typeof uni !== 'undefined' && uni.onNetworkStatusChange) {
      uni.onNetworkStatusChange((res: any) => {
        const wasOffline = !this.isOnline;
        this.isOnline = res.isConnected;
        
        // 网络从离线恢复到在线时，尝试上报缓存的错误
        if (wasOffline && this.isOnline) {
          console.log('[ErrorReporter] 网络已恢复，开始上报缓存的错误');
          this.retryCachedErrors();
        }
      });
    }
  }

  private startFlushTimer(): void {
    const config = this.configManager.getConfig();
    
    this.flushTimer = setInterval(() => {
      this.flush();
    }, config.flushInterval) as any;
  }

  private getUserAgent(): string {
    const platformType = this.platformAdapter.getPlatformType();
    
    if (platformType === PlatformType.H5) {
      // H5环境：尝试获取navigator.userAgent
      if (typeof navigator !== 'undefined' && navigator.userAgent) {
        return navigator.userAgent;
      }
    }
    
    // 非H5环境或无法获取时返回默认值
    return 'UniApp';
  }

  private getCurrentUrl(): string {
    const platformType = this.platformAdapter.getPlatformType();
    
    if (platformType === PlatformType.H5) {
      // H5环境：获取当前页面URL
      if (typeof window !== 'undefined' && window.location) {
        return window.location.href;
      }
    } else {
      // 非H5环境：获取当前页面路径
      try {
        const pages = getCurrentPages();
        if (pages && pages.length > 0) {
          const currentPage = pages[pages.length - 1];
          return currentPage.route || currentPage.__route__ || '';
        }
      } catch (err) {
        console.warn('[ErrorReporter] 获取当前页面失败:', err);
      }
    }
    
    return '';
  }

  destroy(): void {
    if (this.flushTimer) {
      clearInterval(this.flushTimer);
    }
    // 销毁时尝试上报剩余的缓存错误
    this.retryCachedErrors();
  }
}